﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Assimp;
using Assimp.Configs;

namespace Apparat.Renderables.AssimpMeshInterface
{
    public class MeshLoader
    {
       
        public static void Import(String fileName)
        {
            try
            {
                AssimpImporter importer = new AssimpImporter();
                NormalSmoothingAngleConfig config = new NormalSmoothingAngleConfig(66.0f);
                importer.SetConfig(config);
                //This is how we add a logging callback 
                LogStream logstream = new LogStream(delegate(String msg, String userData)
                {
                    //Console.WriteLine(msg);
                });
                importer.AttachLogStream(logstream);
                Assimp.Scene model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);



                if (model.HasMeshes)
                {
                    AssimpCarModel amodel = new AssimpCarModel();

                    if (model.HasMaterials)
                    {
                        amodel.AssimpMaterial = model.Materials;
                        // load Textures

                        string path = System.IO.Path.GetDirectoryName(fileName);

                        foreach (Material mat in amodel.AssimpMaterial)
                        {
                            //string file = mat.

                            TextureSlot texSl = mat.GetTexture(TextureType.Diffuse, 0);
                            if (texSl.FilePath != null)
                            {
                                //string texPath = path + "\\" + texSl.FilePath;
                                Apparat.Renderables.AssimpMeshInterface.TextureManager.Instance.AddTexture(path, texSl.FilePath);


                            }

                        }



                    }

                    ReadHierarchy(model.RootNode, false);
                    List<AssimpMesh> meshes = new List<AssimpMesh>();

                    foreach (Mesh mesh in model.Meshes)
                    {

                        Material mat = model.Materials[mesh.MaterialIndex];

                        AssimpMesh m = null;
                        m = new AssimpMesh(mesh, mat);

                        if (m != null)
                        {
                            meshes.Add(m);
                            //Apparat.Scene.Instance.addRenderObject(m);
                        }
                    }

                    if (meshes.Count > 0)
                    {
                        AssimpMesh[] arr = meshes.ToArray();
                        amodel.AssimpMesh = arr;
                        amodel.Root = model.RootNode;
                        Apparat.Scene.Instance.AddRenderObject(amodel);
                        //RenderControl.carModel = amodel;

                        amodel.FrontRightWheel = GetNode(model.RootNode, "wheel_ti40_1");
                        amodel.RearRightWheel = GetNode(model.RootNode, "wheel_ti40_2");
                        amodel.FrontLeftWheel = GetNode(model.RootNode, "wheel_ti40_3");
                        amodel.RearLeftWheel = GetNode(model.RootNode, "wheel_ti40_4");


                    }


                }



                importer.Dispose();
            }
            catch (Exception ex)
            {
                Console.Write(ex.ToString());
            }
        }

        private static Node GetNode(Node node, string p)
        {
            if (node.Name == p)
                return node;

            if (node.HasChildren)
            {
                foreach (Assimp.Node child in node.Children)
                {
                    if (GetNode(child, p) != null)
                        return GetNode(child, p);
                }
            }

            return null;
        }

        static int level = 0;
        private static void ReadHierarchy(Assimp.Node node, bool verbose)
        {
            level++;

            if (verbose)
            {
                for (int i = 0; i < level; i++)
                {
                    Console.Write("-");
                }
                Console.WriteLine(node.Name);
            }


            if (node.HasChildren)
            {
                foreach (Assimp.Node child in node.Children)
                {
                    ReadHierarchy(child, verbose);
                }
            }
            level--;
        }
    }
}
